﻿using System;

using zijian666.Converts.Abstractions;
using zijian666.Converts.Core;
using zijian666.Converts.Extensions;

namespace zijian666.Converts.Convertor.Base;

/// <summary>
/// 代理转换器，转换器输出类型可兼容, 但不能直接协变时, 可使用代理方式执行
/// </summary>
/// <param name="convertor"></param>
public class ProxyConvertor<TSub, TBase>(IConvertor<TSub> convertor) : IObjectProxy, IConvertor<TBase>
    where TSub : TBase
{

    /// <inheritdoc/>
    public uint Priority => InnerConvertor.Priority;

    /// <summary>
    /// 被代理的转换器
    /// </summary>
    public IConvertor<TSub> InnerConvertor { get; } = (convertor as ProxyConvertor<TSub, TBase>)?.InnerConvertor ?? convertor ?? throw new ArgumentNullException(nameof(convertor));

    /// <inheritdoc />
    ConvertResult<TBase> IConvertor<TBase>.Convert(IConvertContext context, object? input)
    {
        if (context is null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        var result = InnerConvertor.Convert(context, input);
        if (result.Success)
        {
            return new(result.Value);
        }
        return result.Exception!;
    }

    /// <summary>
    /// 将值转到指定类型 <see cref="TSub"/> 然后再转为其父类 <see cref="TBase"/> 返回
    /// </summary>
    public static ConvertResult<TBase> Convert(IConvertContext context, object? input)
    {
        if (context is null)
        {
            throw new ArgumentNullException(nameof(context));
        }
        var convertor = context.GetConvertor<TSub>()!;
        var result = convertor.Convert(context, input);
        if (result.Success)
        {
            return new(result.Value);
        }
        return result.Exception!;
    }


    object? IObjectProxy.GetActualObject() => InnerConvertor;
}
